/**
 * @PROJECT 
 * @DATE 2018年7月20日 下午3:12:24
 * @AUTHOR LUYU
 */
package com.kool.evowkf.service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONObject;
import com.kool.core.CoreConstants;
import com.kool.core.cache.KCache;
import com.kool.core.context.ContextHolder;
import com.kool.core.exception.AppException;
import com.kool.core.util.GlobalDefineUtils;
import com.kool.core.util.StringUtils;
import com.kool.evowkf.WKFConstants;
import com.kool.evowkf.bean.SyWkfAgentBean;
import com.kool.evowkf.bean.SyWkfDefineBean;
import com.kool.evowkf.bean.SyWkfEntityBean;
import com.kool.evowkf.bean.SyWkfEntityBusinessBean;
import com.kool.evowkf.bean.SyWkfNodeBean;
import com.kool.evowkf.bean.SyWkfNodeTemplateBean;
import com.kool.evowkf.bean.SyWkfRecordBean;
import com.kool.evowkf.bean.SyWkfRouteBean;
import com.kool.evowkf.bean.SyWkfWorkerBean;
import com.kool.evowkf.bean.SyWkfWorkgroupBean;
import com.kool.evowkf.bean.io.approve.CMADDAPRNODEXBean;
import com.kool.evowkf.bean.io.approve.CMADDAPRWORKERXBean;
import com.kool.evowkf.bean.io.approve.CMQRYTREEZBean;
import com.kool.evowkf.bean.io.approve.CMWORKERINFOZBean;
import com.kool.evowkf.dao.SyWkfAgentDao;
import com.kool.evowkf.dao.SyWkfDefineDao;
import com.kool.evowkf.dao.SyWkfEntityBusinessDao;
import com.kool.evowkf.dao.SyWkfEntityDao;
import com.kool.evowkf.dao.SyWkfNodeDao;
import com.kool.evowkf.dao.SyWkfNodeTemplateDao;
import com.kool.evowkf.dao.SyWkfRecordDao;
import com.kool.evowkf.dao.SyWkfRouteDao;
import com.kool.evowkf.dao.SyWkfWorkerDao;
import com.kool.evowkf.dao.SyWkfWorkgroupDao;
import com.kool.system.bean.SyUserInfoBean;
import com.kool.system.service.CounterService;

/**
 * @DESCRIBE 审批流配置业务处理类
 * @AUTHOR LUYU
 * @DATE 2018年7月20日 下午3:12:24
 *
 */
@Service
public class ApproveService {
	private static Logger logger = Logger.getLogger(ApproveService.class);

	@Autowired
	private SyWkfDefineDao defDao;

	@Autowired
	private SyWkfEntityBusinessDao busDao;

	@Autowired
	private SyWkfEntityDao entityDao;

	@Autowired
	private SyWkfNodeDao nodeDao;

	@Autowired
	private SyWkfRouteDao routeDao;

	@Autowired
	private SyWkfWorkgroupDao wgDao;

	@Autowired
	private SyWkfWorkerDao workerDao;

	@Autowired
	private CounterService cntService;

	@Autowired
	private SyWkfNodeTemplateDao nodeTmpDao;

	@Autowired
	private SyWkfRecordDao rcdDao;

	@Autowired
	private SyWkfAgentDao agentDao;

	/**
	 * @DESCRIBE 查询审批流实例
	 * @DATE 2018年7月20日 下午3:18:43
	 *
	 * @param userCid
	 * @return
	 * @throws AppException
	 */
	public List<CMQRYTREEZBean> queryApproveEntity(String userCid) throws AppException {
		// 查询审批流的流程定义
		SyWkfDefineBean pk = new SyWkfDefineBean();
		pk.setSwdWkfCode(WKFConstants.SWD_WKF_CODE_APPROVE);
		SyWkfDefineBean define = defDao.selectByPK(pk);
		if (null == define) {
			throw new AppException("WF000002", WKFConstants.SWD_WKF_CODE_APPROVE);// 审批流配置错误，无流程定义[%1]
		}

		CMQRYTREEZBean wkfDefNode = new CMQRYTREEZBean();
		wkfDefNode.setNodeId(WKFConstants.SWD_WKF_CODE_APPROVE);
		wkfDefNode.setRootNodeId(WKFConstants.SWD_WKF_CODE_APPROVE);
		wkfDefNode.setDeep("0");
		wkfDefNode.setSeq("0");
		wkfDefNode.setTitle("多级审批");
		JSONObject joDef = new JSONObject();
		joDef.put("wkfCode", define.getSwdWkfCode());
		joDef.put("wkfName", define.getSwdWkfName());
		joDef.put("checkFlag", define.getSwdCheckFlag());
		joDef.put("routeType", define.getSwdRouteType());
		GlobalDefineUtils.addTransformation(joDef, "checkFlag", "SWD_CHECK_FLAG");
		GlobalDefineUtils.addTransformation(joDef, "routeType", "SWD_ROUTE_TYPE");
		wkfDefNode.setContent(joDef.toJSONString());

		SyWkfEntityBusinessBean info = new SyWkfEntityBusinessBean();
		info.setSebWkfCode(WKFConstants.SWD_WKF_CODE_APPROVE);
		List<SyWkfEntityBusinessBean> listBus = busDao.select(info);
		if (null == listBus || listBus.size() <= 0) {
			throw new AppException("WF000003");// 未设置使用审批流的业务
		}

		// 查询用户所在工作流实例
		List<SyWkfEntityBean> listEntity = queryEntityOfApprove(userCid);

		// 查询用户所在工作流实例的所有结点
		List<SyWkfNodeBean> listNode = queryNodesOfApprove(userCid);

		List<CMQRYTREEZBean> listBusNodes = new ArrayList<>();
		List<CMQRYTREEZBean> listEntNodes = new ArrayList<>();
		List<CMQRYTREEZBean> listNodeNodes = new ArrayList<>();
		for (int i = 0; i < listBus.size(); i++) {
			CMQRYTREEZBean busNode = new CMQRYTREEZBean();
			String busType = listBus.get(i).getSebBusinessType();
			busNode.setNodeId(busType);
			busNode.setFatNodeId(WKFConstants.SWD_WKF_CODE_APPROVE);
			busNode.setRootNodeId(WKFConstants.SWD_WKF_CODE_APPROVE);
			busNode.setDeep("1");
			busNode.setSeq(String.valueOf(i));
			busNode.setTitle(GlobalDefineUtils.transfer("SEB_BUSINESS_TYPE", busType));
			JSONObject joBus = new JSONObject();
			joBus.putAll(joDef);
			joBus.put("businessType", busType);
			busNode.setContent(joBus.toJSONString());
			listBusNodes.add(busNode);

			if (listEntity != null && listEntity.size() > 0) {
				for (int j = 0; j < listEntity.size(); j++) {
					String entBusType = listEntity.get(j).getSweBusinessType();
					if (entBusType.equals(busType)) {
						CMQRYTREEZBean entityNode = new CMQRYTREEZBean();
						String entityCid = listEntity.get(j).getSweEntityCid();
						entityNode.setNodeId(entityCid);
						entityNode.setFatNodeId(busType);
						entityNode.setRootNodeId(WKFConstants.SWD_WKF_CODE_APPROVE);
						entityNode.setDeep("2");
						entityNode.setSeq(String.valueOf(j));
						entityNode.setTitle(listEntity.get(j).getSweEntityName());
						JSONObject joEnt = new JSONObject();
						joEnt.put("entityCid", listEntity.get(j).getSweEntityCid());
						joEnt.put("entityName", listEntity.get(j).getSweEntityName());
						joEnt.put("wkfCode", listEntity.get(j).getSweWkfCode());
						joEnt.put("businessType", listEntity.get(j).getSweBusinessType());
						joEnt.put("matchValue", listEntity.get(j).getSweMatchValue());
						joEnt.put("nodeHead", listEntity.get(j).getSweNodeHead());
						joEnt.put("nodeHeadName", listEntity.get(j).getSweNodeHeadName());
						joEnt.put("state", listEntity.get(j).getSweState());
						GlobalDefineUtils.addTransformation(joDef, "businessType", "SWE_BUSINESS_TYPE");
						GlobalDefineUtils.addTransformation(joDef, "state", "SWE_STATE");
						entityNode.setContent(joEnt.toJSONString());
						listEntNodes.add(entityNode);

						int l = 0;
						for (int k = 0; k < listNode.size(); k++) {
							String nodeEntCid = listNode.get(k).getSwnEntityCid();
							if (nodeEntCid.equals(entityCid)) {
								CMQRYTREEZBean node = new CMQRYTREEZBean();
								String nodeCid = listNode.get(k).getSwnNodeCid();
								node.setNodeId(nodeCid);
								node.setFatNodeId(entityCid);
								node.setRootNodeId(WKFConstants.SWD_WKF_CODE_APPROVE);
								node.setDeep("3");
								node.setSeq(String.valueOf(l));
								node.setTitle(listNode.get(k).getSwnNodeName());
								JSONObject joNode = new JSONObject();
								joNode.put("nodeCid", listNode.get(k).getSwnNodeCid());
								joNode.put("nodeName", listNode.get(k).getSwnNodeName());
								joNode.put("wgCid", listNode.get(k).getSwnWgCid());
								node.setContent(joNode.toJSONString());
								listNodeNodes.add(node);
								l++;
							}
						}
					}
				}
			}

		}
		List<CMQRYTREEZBean> ret = new ArrayList<>();
		ret.add(wkfDefNode);
		ret.addAll(listBusNodes);
		ret.addAll(listEntNodes);
		ret.addAll(listNodeNodes);
		return ret;
	}

	/**
	 * @DESCRIBE 查询用户所在工作流实例，用户号为空时查询所有用户的实例
	 * @DATE 2018年7月22日 上午11:28:11
	 *
	 * @param userCid
	 * @return
	 */
	private List<SyWkfEntityBean> queryEntityOfApprove(String userCid) {
		StringBuilder sb = new StringBuilder();
		sb.append("SELECT DISTINCT A.* FROM SY_WKF_ENTITY A, SY_WKF_NODE B,SY_WKF_WORKER C ");
		sb.append("WHERE A.SWE_ENTITY_CID = B.SWN_ENTITY_CID ");
		sb.append("AND B.SWN_WG_CID = C.SWO_WG_CID ");
		sb.append("AND A.SWE_STATE = 'A' ");
		if (StringUtils.isEmpty(userCid) == false) {
			sb.append("AND C.SWO_USER_CID = '").append(userCid).append("'");
		}
		logger.debug(sb.toString());

		List<SyWkfEntityBean> listEnt = new ArrayList<>();
		List<Map<String, Object>> listRet = entityDao.selectBySql(sb.toString());
		for (Map<String, Object> map : listRet) {
			listEnt.add(SyWkfEntityBean.DBResultToBean(map));
		}

		return listEnt;
	}

	/**
	 * @DESCRIBE 查询用户所在工作流实例的所有结点，用户号为空时查询所有用户的
	 * @DATE 2018年7月20日 下午4:07:01
	 * @param userCid
	 *
	 * @return
	 */
	private List<SyWkfNodeBean> queryNodesOfApprove(String userCid) {
		StringBuilder sb = new StringBuilder();
		sb.append("SELECT A.* FROM SY_WKF_NODE A, SY_WKF_ENTITY B, SY_WKF_DEFINE C ");
		sb.append("WHERE A.SWN_ENTITY_CID = B.SWE_ENTITY_CID ");
		sb.append("AND B.SWE_WKF_CODE = C.SWD_WKF_CODE ");
		sb.append("AND C.SWD_WKF_CODE='").append(WKFConstants.SWD_WKF_CODE_APPROVE).append("' ");
		sb.append("AND B.SWE_STATE='A' ");
		sb.append("AND B.SWE_ENTITY_CID IN (");
		sb.append("SELECT DISTINCT A.SWE_ENTITY_CID FROM SY_WKF_ENTITY A, SY_WKF_NODE B,SY_WKF_WORKER C ");
		sb.append("WHERE A.SWE_ENTITY_CID = B.SWN_ENTITY_CID ");
		sb.append("AND B.SWN_WG_CID = C.SWO_WG_CID ");
		sb.append("AND A.SWE_STATE = 'A' ");
		if (StringUtils.isEmpty(userCid) == false) {
			sb.append("AND C.SWO_USER_CID = '").append(userCid).append("'");
		}
		sb.append(") ");
		sb.append("AND A.SWN_STATE='A'");
		logger.debug(sb.toString());

		List<SyWkfNodeBean> listNodes = new ArrayList<>();
		List<Map<String, Object>> listRet = entityDao.selectBySql(sb.toString());
		for (Map<String, Object> map : listRet) {
			listNodes.add(SyWkfNodeBean.DBResultToBean(map));
		}
		return listNodes;
	}

	/**
	 * @DESCRIBE 增加审批流实例
	 * @DATE 2018年7月21日 下午3:54:42
	 *
	 * @param entity
	 * @param listNodes
	 * @param listWorkers
	 * @throws AppException
	 */
	public void addApproveEntity(SyWkfEntityBean entity, List<CMADDAPRNODEXBean> listIoNodes,
			List<CMADDAPRWORKERXBean> listIoWorkers) throws AppException {
		validate(entity, listIoNodes, listIoWorkers);

		// 审批流单实例校验
		SyWkfEntityBean info = new SyWkfEntityBean();
		info.setSweWkfCode(entity.getSweWkfCode());
		info.setSweBusinessType(entity.getSweBusinessType());
		info.setSweState(WKFConstants.SWE_STATE_ACTIVE);
		List<SyWkfEntityBean> listEntity = entityDao.select(info);
		if (listEntity.size() > 0) {
			throw new AppException("WF000055");// 每个业务类型的审批流只能有一个正常状态的实例
		}
		// 设置审批流默认值
		String entityCid = "E" + cntService.getNextNumber(WKFConstants.CNT_ENTITY_CID);// 实例编号
		entity.setSweEntityCid(entityCid);
		entity.setSweState(WKFConstants.SWE_STATE_ACTIVE);

		List<SyWkfNodeBean> listNodes = new ArrayList<>();
		List<SyWkfRouteBean> listRoutes = new ArrayList<>();
		List<SyWkfWorkgroupBean> listWg = new ArrayList<>();
		List<SyWkfWorkerBean> listWorkers = new ArrayList<>();
		int seq = 0;
		while (listIoNodes.size() > 0) {
			// 取出序号最小的结点，并移除
			CMADDAPRNODEXBean ioNodeMinSeq = getMinSeqAndRemove(listIoNodes);
			// 构造结点
			SyWkfNodeBean node = new SyWkfNodeBean();
			String nodeCid = "N" + cntService.getNextNumber(WKFConstants.CNT_NODE_CID);// 结点编号
			node.setSwnNodeCid(nodeCid);
			node.setSwnNodeName(ioNodeMinSeq.getNodeName());
			node.setSwnEntityCid(entityCid);
			String wgCid = cntService.getNextNumber(WKFConstants.CNT_WG_CID);// 工作组编号
			node.setSwnWgCid(wgCid);
			node.setSwnEventType(WKFConstants.SWN_EVENT_TYPE_APPROVE);
			node.setSwnRecordType(WKFConstants.SWN_RECORD_TYPE_NONE);
			node.setSwnRouteStrategy(WKFConstants.SWN_ROUTE_STRATEGY_RANDOM);
			node.setSwnBackStrategy(WKFConstants.SWN_BACK_STRATEGY_FINISH);
			node.setSwnIsAuto(WKFConstants.SWN_IS_AUTO_NO);
			node.setSwnState(WKFConstants.SWN_STATE_ACTIVE);
			// 最后一个结点是终审
			if (listIoNodes.size() == 0) {
				node.setSwnEventRule(WKFConstants.SWN_EVENT_RULE_SERVICESYN);
				SyWkfNodeTemplateBean tempInfo = new SyWkfNodeTemplateBean();
				tempInfo.setSntWkfCode(entity.getSweWkfCode());
				List<SyWkfNodeTemplateBean> listTemp = nodeTmpDao.select(tempInfo);
				if (null == listTemp || listTemp.size() != 1) {
					throw new AppException("WF000004");// 结点模板配置错误
				}
				node.setSwnEventExt(listTemp.get(0).getSntEventExt());
			} else {
				node.setSwnEventRule(WKFConstants.SWN_EVENT_RULE_WKFONLY);
			}
			listNodes.add(node);

			// 实例增加首结点信息
			if (seq == 0) {
				entity.setSweNodeHead(node.getSwnNodeCid());
				entity.setSweNodeHeadName(node.getSwnNodeName());
			}
			// 构造路由
			if (seq > 0) {
				SyWkfRouteBean route = new SyWkfRouteBean();
				route.setSwrRouteCid("R" + cntService.getNextNumber(WKFConstants.CNT_ROUTE_CID));
				route.setSwrEntityCid(entity.getSweEntityCid());
				SyWkfNodeBean headNode = listNodes.get(listNodes.size() - 2);
				route.setSwrNodeHead(headNode.getSwnNodeCid());
				route.setSwrNodeHeadName(headNode.getSwnNodeName());
				route.setSwrNodeTail(node.getSwnNodeCid());
				route.setSwrNodeTailName(node.getSwnNodeName());
				route.setSwrRouteState(WKFConstants.SWR_STATE_ACTIVE);
				listRoutes.add(route);
			}
			// 构造工作组
			SyWkfWorkgroupBean workgroup = new SyWkfWorkgroupBean();
			workgroup.setSwwWgCid(wgCid);
			workgroup.setSwwWgName(node.getSwnNodeName());
			workgroup.setSwwWgType(WKFConstants.SWW_WG_TYPE_W2);
			workgroup.setSwwWkfCode(entity.getSweWkfCode());
			workgroup.setSwwState(WKFConstants.SWW_STATE_ACTIVE);
			listWg.add(workgroup);

			// 取出序号相同的工作组员工
			List<CMADDAPRWORKERXBean> listGroupWorkers = getWorkerWithSameSeq(ioNodeMinSeq.getSeq(), listIoWorkers);
			for (CMADDAPRWORKERXBean ioWorker : listGroupWorkers) {
				SyWkfWorkerBean worker = new SyWkfWorkerBean();
				worker.setSwoWgCid(wgCid);
				worker.setSwoUserCid(ioWorker.getUserCid());
				worker.setSwoLoginName(ioWorker.getLoginName());
				listWorkers.add(worker);
			}
			seq++;
		}

		entityDao.insert(entity);
		nodeDao.insertBatch(listNodes);
		routeDao.insertBatch(listRoutes);
		wgDao.insertBatch(listWg);
		workerDao.insertBatch(listWorkers);

	}

	/**
	 * @DESCRIBE 取出序号相同的工作组员工
	 * @DATE 2018年7月21日 下午4:33:45
	 *
	 * @param seq
	 * @param listIoWorkers
	 * @return
	 */
	private List<CMADDAPRWORKERXBean> getWorkerWithSameSeq(String seq, List<CMADDAPRWORKERXBean> listIoWorkers) {
		List<CMADDAPRWORKERXBean> list = new ArrayList<>();
		for (CMADDAPRWORKERXBean ioWorker : listIoWorkers) {
			if (seq.equals(ioWorker.getSeq())) {
				list.add(ioWorker);
			}
		}
		return list;
	}

	/**
	 * @DESCRIBE
	 * @DATE 2018年7月21日 下午4:21:19
	 *
	 * @param listIoNodes
	 * @return
	 */
	private CMADDAPRNODEXBean getMinSeqAndRemove(List<CMADDAPRNODEXBean> listIoNodes) {
		CMADDAPRNODEXBean min = listIoNodes.get(0);
		int index = 0;
		for (int i = 1; i < listIoNodes.size(); i++) {
			CMADDAPRNODEXBean ioNode = listIoNodes.get(i);
			if (Integer.valueOf(ioNode.getSeq()) < Integer.valueOf(min.getSeq())) {
				min = ioNode;
				index = i;
			}
		}
		listIoNodes.remove(index);
		return min;
	}

	/**
	 * @DESCRIBE
	 * @DATE 2018年7月21日 下午3:55:38
	 *
	 * @param entity
	 * @param listNodes
	 * @param listWorkers
	 * @throws AppException
	 */
	private void validate(SyWkfEntityBean entity, List<CMADDAPRNODEXBean> listNodes,
			List<CMADDAPRWORKERXBean> listWorkers) throws AppException {
		if (StringUtils.isEmpty(entity.getSweEntityName())) {
			throw new AppException("WF000041");// 实例名称不能为空！
		}
		if (StringUtils.isEmpty(entity.getSweWkfCode())) {
			throw new AppException("WF000042");// 模式代号不能为空！
		}
		if (StringUtils.isEmpty(entity.getSweBusinessType())) {
			throw new AppException("WF000043");// 业务类型不能为空！
		}
		if (null == listNodes || listNodes.size() <= 0) {
			throw new AppException("WF000044");// 流程结点个数必须大于0！
		}
		for (CMADDAPRNODEXBean ioNode : listNodes) {
			String seq = ioNode.getSeq();
			boolean hasWorker = false;
			for (CMADDAPRWORKERXBean ioWorker : listWorkers) {
				String seqW = ioWorker.getSeq();
				if (seq.equals(seqW)) {
					hasWorker = true;
					break;
				}
			}
			if (hasWorker == false) {
				throw new AppException("WF000045");// 每个结点至少要有一名工作组组员！
			}
		}
	}

	/**
	 * @DESCRIBE 查询结点工作组组员
	 * @DATE 2018年7月21日 下午9:43:04
	 *
	 * @param nodeCid
	 * @return
	 */
	public List<CMWORKERINFOZBean> queryNodeWorkers(String nodeCid) {
		StringBuilder sb = new StringBuilder();
		sb.append("SELECT SWO_USER_CID,SWO_LOGIN_NAME,SWA_AGENT_USER_CID,SWA_AGENT_LOGIN_NAME FROM ( ");
		sb.append("SELECT SWO_USER_CID,SWO_LOGIN_NAME,SWN_NODE_CID FROM SY_WKF_NODE A,SY_WKF_WORKER B ");
		sb.append("WHERE A.SWN_WG_CID=B.SWO_WG_CID ) C ");
		sb.append("LEFT OUTER JOIN SY_WKF_AGENT D ON C.SWN_NODE_CID=D.SWA_NODE_CID AND C.SWO_USER_CID=D.SWA_USER_CID ");
		sb.append("WHERE 1=1 ");
		if (StringUtils.isEmpty(nodeCid) == false) {
			sb.append("AND SWN_NODE_CID='").append(nodeCid).append("'");
		}
		logger.debug(sb.toString());

		List<Map<String, Object>> listRet = routeDao.selectBySql(sb.toString());
		List<CMWORKERINFOZBean> listOut = new ArrayList<>();
		for (Map<String, Object> map : listRet) {
			CMWORKERINFOZBean ioOut = new CMWORKERINFOZBean();
			ioOut.setUserCid((String) map.get("SWO_USER_CID"));
			ioOut.setLoginName((String) map.get("SWO_LOGIN_NAME"));
			ioOut.setAgentUserCid((String) map.get("SWA_AGENT_USER_CID"));
			ioOut.setAgentLoginName((String) map.get("SWA_AGENT_LOGIN_NAME"));
			listOut.add(ioOut);
		}
		return listOut;
	}

	/**
	 * @DESCRIBE 关闭审批流实例
	 * @DATE 2018年7月22日 上午9:33:34
	 *
	 * @param entity
	 * @throws AppException
	 */
	public void closeApproveEntity(SyWkfEntityBean pk) throws AppException {
		// 查询实例
		SyWkfEntityBean entity = entityDao.selectByPK(pk);
		String entityCid = pk.getSweEntityCid();
		if (null == entity) {
			throw new AppException("WF000005", entityCid);// 审批流实例[%1]不存在
		}
		// 查询执行记录中是否有未完成的实例关联记录
		SyWkfRecordBean info = new SyWkfRecordBean();
		info.setSrcEntityCid(entityCid);
		info.setSrcState(WKFConstants.SRC_STATE_FINISH);
		List<SyWkfRecordBean> listRcd = rcdDao.select(info);
		// 如果有关联未完成记录，则实例状态更新为待关闭，否组状态更新为关闭
		if (listRcd != null && listRcd.size() > 0) {
			entity.setSweState(WKFConstants.SWE_STATE_PADDING);
		} else {
			entity.setSweState(WKFConstants.SWE_STATE_CLOSE);
		}

		entityDao.update(entity);
	}

	/**
	 * @DESCRIBE 修改审批流实例
	 * @DATE 2018年7月22日 上午10:03:26
	 *
	 * @param entityInfo
	 * @param listNodes
	 * @param listWorkers
	 * @throws AppException
	 */
	public void updateApproveEntity(SyWkfEntityBean entityInfo, List<CMADDAPRNODEXBean> listNodes,
			List<CMADDAPRWORKERXBean> listWorkers) throws AppException {
		validate(entityInfo, listNodes, listWorkers);
		// 查询实例
		SyWkfEntityBean entity = entityDao.selectByPK(entityInfo);
		String entityCid = entityInfo.getSweEntityCid();
		if (null == entity) {
			throw new AppException("WF000005", entityCid);// 审批流实例[%1]不存在
		}
		// 查询执行记录中是否有未完成的实例关联记录
		SyWkfRecordBean info = new SyWkfRecordBean();
		info.setSrcEntityCid(entityCid);
		info.setSrcState(WKFConstants.SRC_STATE_FINISH);
		List<SyWkfRecordBean> listRcd = rcdDao.select(info);
		// 如果有关联未完成记录，则新增实例，原实例更新为待关闭;否则修改原实例
		if (listRcd != null && listRcd.size() > 0) {
			entity.setSweState(WKFConstants.SWE_STATE_PADDING);
		} else {
			entity.setSweState(WKFConstants.SWE_STATE_CLOSE);
		}
		entityDao.update(entity);
		addApproveEntity(entityInfo, listNodes, listWorkers);
	}

	/**
	 * @DESCRIBE 代理
	 * @DATE 2018年7月22日 下午12:21:00
	 *
	 * @param agent
	 * @throws AppException
	 */
	public void agent(SyWkfAgentBean agent) throws AppException {
		if (null == agent) {
			throw new AppException("WF000046");// 代理人信息为空
		}
		String userCid = ContextHolder.getReqContext().getUserCid();
		// 查询结点工作组中是否包含自己
		boolean hasMe = false;
		List<CMWORKERINFOZBean> listWorker = queryNodeWorkers(agent.getSwaNodeCid());
		for (CMWORKERINFOZBean worker : listWorker) {
			if (worker.getUserCid().equals(userCid)) {
				hasMe = true;
				break;
			}
		}
		if (hasMe == false) {
			throw new AppException("WF000050");// 该结点工作组中不包含自己，不能设置代理
		}
		if (userCid.equals(agent.getSwaAgentUserCid())) {
			throw new AppException("WF000049");// 代理人不能是自己
		}
		SyUserInfoBean user = (SyUserInfoBean) KCache.get(CoreConstants.KCACHE_USER, userCid);
		String loginName = user.getSuiLoginName();

		SyWkfAgentBean info = new SyWkfAgentBean();
		info.setSwaUserCid(userCid);
		info.setSwaLoginName(loginName);
		info.setSwaState(WKFConstants.SWE_STATE_ACTIVE);
		List<SyWkfAgentBean> listAgent = agentDao.select(info);
		if (listAgent != null && listAgent.size() > 0) {
			throw new AppException("WF000047");// 已有代理，请先取消原代理人
		}

		agent.setSwaUserCid(userCid);
		agent.setSwaLoginName(loginName);
		agent.setSwaState(WKFConstants.SWE_STATE_ACTIVE);
		agentDao.insert(agent);
	}

	/**
	 * @DESCRIBE 取消代理
	 * @DATE 2018年7月22日 下午12:45:26
	 *
	 * @param nodeCid
	 * @throws AppException
	 */
	public void cancelAgent(String nodeCid) throws AppException {
		if (StringUtils.isEmpty(nodeCid)) {
			throw new AppException("WF000048");// 取消代理结点信息为空
		}
		String userCid = ContextHolder.getReqContext().getUserCid();
		SyWkfAgentBean info = new SyWkfAgentBean();
		info.setSwaUserCid(userCid);
		info.setSwaNodeCid(nodeCid);
		agentDao.deletes(info);
	}

}
